/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package cn.ac.iie.di.ban.ycl.ybk.e2p.yb.tools.fastutil;

import cn.ac.iie.di.ban.ycl.ybk.e2p.yb.main.BanBkE2p;
import static cn.ac.iie.di.ban.ycl.ybk.e2p.yb.tools.fastutil.FileManagerConfig.CLIENT_CONFIG_FILE;
import static cn.ac.iie.di.ban.ycl.ybk.e2p.yb.tools.fastutil.FileManagerConfig.PROTOCOL;
import static cn.ac.iie.di.ban.ycl.ybk.e2p.yb.tools.fastutil.FileManagerConfig.SEPARATOR1;
import static cn.ac.iie.di.ban.ycl.ybk.e2p.yb.tools.fastutil.FileManagerConfig.SEPARATOR2;
import static cn.ac.iie.di.ban.ycl.ybk.e2p.yb.tools.fastutil.FileManagerConfig.TRACKER_NGNIX_PORT;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.InetSocketAddress;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Properties;
import org.apache.log4j.Logger;
import org.csource.common.NameValuePair;
import org.csource.fastdfs.ClientGlobal;
import org.csource.fastdfs.FileInfo;
import org.csource.fastdfs.ServerInfo;
import org.csource.fastdfs.StorageClient;
import org.csource.fastdfs.StorageServer;
import org.csource.fastdfs.TrackerClient;
import org.csource.fastdfs.TrackerGroup;
import org.csource.fastdfs.TrackerServer;

/**
 *
 * @author wmr
 */
public class FileManager implements FileManagerConfig {

    private static final long serialVersionUID = 1L;
    private static Logger logger = Logger.getLogger(FileManager.class);
    private static TrackerClient trackerClient;
    private static TrackerServer trackerServer;
    private static StorageServer storageServer;
    private static StorageClient storageClient;

    private static int conn_timeout;
    private static int net_timeout;
    private static String charset = "";
    private static int http_tracker_http_port;
    private static boolean http_anti_steal_token;
    private static String http_secret_key = "";
    private static String tracker_server_group = "";
    private static int tracker_server_port;

    static { // Initialize Fast DFS Client configurations
        InputStream in = null;
        try {
//            String classPath = new File(FileManager.class.getResource("/").getFile()).getCanonicalPath();
//            String fdfsClientConfigFilePath = classPath + File.separator + CLIENT_CONFIG_FILE;
//            String fdfsClientConfigFilePath = BanBkE2p.confDir + File.separator + CLIENT_CONFIG_FILE;
//            String fdfsClientConfigFilePath = BanBkE2p.confDir + "/" + CLIENT_CONFIG_FILE;
//            logger.info("Fast DFS configuration file path:" + fdfsClientConfigFilePath);
//             ClientGlobal.init(fdfsClientConfigFilePath);
////            ClientGlobal.init(CLIENT_CONFIG_FILE);
            Properties prop = new Properties();
//            String fdfsPath = BanBkE2p.confDir + "/" + "fastdfs.properties";
            String fdfsPath = ClassLoader.getSystemClassLoader().getResource("fastdfs.properties").getFile();
            in = new FileInputStream(fdfsPath);
            prop.load(in);
            in.close();

            conn_timeout = Integer.parseInt(prop.getProperty("connect_timeout").trim());
            net_timeout = Integer.parseInt(prop.getProperty("network_timeout").trim());
            charset = prop.getProperty("charset").trim();
            http_tracker_http_port = Integer.parseInt(prop.getProperty("http_tracker_http_port").trim());
            http_anti_steal_token = Boolean.parseBoolean(prop.getProperty("http_anti_steal_token").trim());
            http_secret_key = prop.getProperty("http_secret_key").trim();
            tracker_server_group = prop.getProperty("tracker_server_group").trim();
            tracker_server_port = Integer.parseInt(prop.getProperty("tracker_server_port").trim());

            //连接超时的时限，单位为毫秒  
            ClientGlobal.setG_connect_timeout(
                    conn_timeout);
            //网络超时的时限，单位为毫秒  
            ClientGlobal.setG_network_timeout(
                    net_timeout);
            ClientGlobal.setG_anti_steal_token(
                    http_anti_steal_token);
            //字符集  
            ClientGlobal.setG_charset(
                    charset);
            ClientGlobal.setG_secret_key(
                    http_secret_key);
            //HTTP访问服务的端口号    
            ClientGlobal.setG_tracker_http_port(
                    http_tracker_http_port);
            String[] trackServers = tracker_server_group.split(";");
            int tsize = trackServers.length;
            InetSocketAddress[] tracker_servers = new InetSocketAddress[tsize];
            for (int i = 0; i < trackServers.length; i++) {
                tracker_servers[i] = new InetSocketAddress(
                    trackServers[i], tracker_server_port);
            }
//            tracker_servers[0] = new InetSocketAddress(
//                    "10.159.81.115", 22122);
//            tracker_servers[1] = new InetSocketAddress(
//                    "10.159.81.117", 22122);
//            tracker_servers[2] = new InetSocketAddress(
//                    "10.159.81.119", 22122);
            ClientGlobal.setG_tracker_group(
                    new TrackerGroup(tracker_servers));
            trackerClient = new TrackerClient();
            trackerServer = trackerClient.getConnection();
            storageClient = new StorageClient(trackerServer, storageServer);

        } catch (Exception e) {
            logger.error("error----" + e.getMessage(), e);
        }
    }

    public static FastPo uploadVideo(FastDFSFile dataFile, FastDFSFile pangFile) {
        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");//设置日期格式
        logger.info(" FileManager start " + df.format(new Date()));
        FastPo fastPo = new FastPo();
        boolean flag = true;
        logger.info("File Name: " + dataFile.getName());
        logger.info("Pang Name: " + pangFile.getName());
//        logger.info("File Name: " + dataFile.getName() + "		File Length: " + dataFile.getContent().length);
//        logger.info("Pang Name: " + pangFile.getName() + "		File Length: " + pangFile.getContent().length);
////        NameValuePair[] meta_list = new NameValuePair[3];
//        meta_list[0] = new NameValuePair("width", "120");
//        meta_list[1] = new NameValuePair("heigth", "120");
//        meta_list[2] = new NameValuePair("author", "ftp");
        NameValuePair[] meta_list = new NameValuePair[1];
        meta_list[0] = new NameValuePair("author", "ftp");
        long startTime = System.currentTimeMillis();
//        String fileAbsolutePath = getAbsolutePath(dataFile,meta_list);
//        String pangAbsolutePath = getAbsolutePath(pangFile,meta_list);
//        logger.info("upload_file time used: " + (System.currentTimeMillis() - startTime) + " ms");

        String fileAbsolutePath = "";
        String pngAbsolutePath = "";
        int up_Data_Connt = 0;
        while (true) {
            fileAbsolutePath = getAbsolutePath(dataFile, meta_list);
            if (fileAbsolutePath != null) {
                logger.info("upload dataFile " + up_Data_Connt + "times success-------------");
                break;
            }
            up_Data_Connt++;
        }

        if (fileAbsolutePath == null) {
//            LoggerUtils.error(logger, "upload file fail, error code: " + storageClient.getErrorCode());
            flag = false;
            fastPo.setUpFlag(flag);
            fastPo.setFilePath("null");
            fastPo.setPangPath("null");
            logger.error("upload file fail, error code: " + storageClient.getErrorCode());
        } else {
            logger.info("upload dataFile success fileAbsolutePath: " + fileAbsolutePath);
//            String pangAbsolutePath = getAbsolutePath(pangFile, meta_list);
            int up_Png_Connt = 0;
            while (true) {
                pngAbsolutePath = getAbsolutePath(pangFile, meta_list);
                if (null != pngAbsolutePath) {
                    logger.info("upload pngFile " + up_Png_Connt + "times success-------------");
                    break;
                }
                up_Png_Connt++;
            }
            if (pngAbsolutePath == null) {
                logger.error("upload pngFile fail, error code: " + storageClient.getErrorCode());
                logger.info("start del dataFile -----------------------------");
                FileManagerUtil fileManagerUtil = new FileManagerUtil();
                String[] paths = fileAbsolutePath.split("/");
                String fileGroup = paths[3];
                logger.info("fileGroup = " + fileGroup);
//                        String errorFilePath = fileAbsolutePath.substring(34, fileAbsolutePath.length());
                String errorFilePath = "";
                for (int i = 4; i < paths.length; i++) {
                    errorFilePath += paths[i] + "/";
                }
                errorFilePath = errorFilePath.substring(0, errorFilePath.length() - 1);
                logger.info("filePath = " + errorFilePath);
                try {
                    fileManagerUtil.delFile(fileGroup, errorFilePath);
                    logger.info("success del dataFile -----------------------------");
                } catch (Exception ex) {
                    logger.error("delete fast dataFile " + fileAbsolutePath + " error" + ex.getMessage(), ex);
                }
                logger.info("end del dataFile -----------------------------");
                flag = false;
                fastPo.setUpFlag(flag);
                fastPo.setFilePath("null");
                fastPo.setPangPath("null");

            } else {
                fastPo.setUpFlag(flag);
                fastPo.setFilePath(fileAbsolutePath);
                fastPo.setPangPath(pngAbsolutePath);
                logger.info("FileManager upload file successfully!!!  " + "fileAbsolutePath: " + " " + fileAbsolutePath);
                logger.info("FileManager upload file successfully!!!  " + "pangAbsolutePath: " + " " + pngAbsolutePath);
            }
        }
//        if (pangAbsolutePath == null) {
////            LoggerUtils.error(logger, "upload file fail, error code: " + storageClient.getErrorCode());
//            flag = false;
//            fastPo.setUpFlag(flag);
//            fastPo.setFilePath("null");
//            fastPo.setPangPath("null");
//            logger.error("upload file fail, error code: " + storageClient.getErrorCode());
//        } else {
//            
//            fastPo.setUpFlag(flag);
//            fastPo.setFilePath(fileAbsolutePath);
//            fastPo.setPangPath(pangAbsolutePath);
//            logger.info("FileManager upload file successfully!!!  " + "fileAbsolutePath: " + " " + fileAbsolutePath);
//            logger.info("FileManager upload file successfully!!!  " + "pangAbsolutePath: " + " " + pangAbsolutePath);
//
//        }
        logger.info(" FileManager end " + df.format(new Date()));
        logger.info("upload_file time used: " + (System.currentTimeMillis() - startTime) + " ms");
        return fastPo;

    }

    public static FastPo upload(FastDFSFile dataFile) {
        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");//设置日期格式
        logger.info(" FileManager start " + df.format(new Date()));
        FastPo fastPo = new FastPo();
        boolean flag = true;
        logger.info("File Name: " + dataFile.getName());
        logger.info("File Ext: " + dataFile.getExt());
//        logger.info("File Name: " + dataFile.getName() + "		File Length: " + dataFile.getContent().length);
        NameValuePair[] meta_list = new NameValuePair[1];
        meta_list[0] = new NameValuePair("author", "ftp");
        long startTime = System.currentTimeMillis();
//        String fileAbsolutePath = getAbsolutePath(dataFile,meta_list);
//        logger.info("upload_file time used: " + (System.currentTimeMillis() - startTime) + " ms");

        String fileAbsolutePath = "";
        int up_Data_Connt = 0;
        while (true) {
            fileAbsolutePath = getAbsolutePath(dataFile, meta_list);
            if (fileAbsolutePath != null) {
                logger.info("upload dataFile " + up_Data_Connt + " times success-------------");
                break;
            }
            up_Data_Connt++;
        }

        if (fileAbsolutePath == null) {
//            LoggerUtils.error(logger, "upload file fail, error code: " + storageClient.getErrorCode());
            flag = false;
            fastPo.setUpFlag(flag);
            fastPo.setFilePath("null");
            fastPo.setPangPath("null");
            logger.error("upload file fail, error code: " + storageClient.getErrorCode());
        } else {
            fastPo.setUpFlag(flag);
            fastPo.setFilePath(fileAbsolutePath);
            fastPo.setPangPath("null");
            logger.info("FileManager upload file successfully!!!  " + "fileAbsolutePath: " + " " + fileAbsolutePath);
//            logger.info("FileManager upload file successfully!!!  " + "pngAbsolutePath: " + " " + "null");

        }
        logger.info(" FileManager end " + df.format(new Date()));
        logger.info("upload_file time used: " + (System.currentTimeMillis() - startTime) + " ms");
        return fastPo;

    }

    public static String getAbsolutePath(FastDFSFile file, NameValuePair[] meta_list) {

//        NameValuePair[] meta_list = new NameValuePair[1];
//        meta_list[0] = new NameValuePair("author", "ftp");
        String[] uploadResults = null;
        String AbsolutePath;
        try {
//            uploadResults = storageClient.upload_file(file.getContent(), file.getExt(), meta_list);
            uploadResults = storageClient.upload_file(file.getName(), file.getExt(), meta_list);
            logger.info("uploadResults --------- " + uploadResults.toString());
            String groupName = uploadResults[0];
            String remoteFileName = uploadResults[1];
//            AbsolutePath = PROTOCOL + trackerServer.getInetSocketAddress().getHostName()
//                    + SEPARATOR2
//                    + TRACKER_NGNIX_PORT
//                    + SEPARATOR1
//                    + groupName
//                    + SEPARATOR1
//                    + remoteFileName;//文件绝对路径
            AbsolutePath = PROTOCOL + trackerServer.getInetSocketAddress().getHostString()
                    + SEPARATOR2
                    + TRACKER_NGNIX_PORT
                    + SEPARATOR1
                    + groupName
                    + SEPARATOR1
                    + remoteFileName;//文件绝对路径
        } catch (IOException e) {
            logger.error("IO Exception when uploadind the file: " + file.getName() + "   " + e.getMessage(), e);
            return null;
        } catch (Exception e) {
            logger.error("Non IO Exception when uploadind the file: " + file.getName() + "   " + e.getMessage(), e);
            return null;
        }
//        String groupName = uploadResults[0];
//        String remoteFileName = uploadResults[1];
//        String AbsolutePath = PROTOCOL + trackerServer.getInetSocketAddress().getHostName()
//                + SEPARATOR2
//                + TRACKER_NGNIX_PORT
//                + SEPARATOR1
//                + groupName
//                + SEPARATOR1
//                + remoteFileName;//文件绝对路径
        return AbsolutePath;
    }

    public static FileInfo getFile(String groupName, String remoteFileName) {
        try {
            return storageClient.get_file_info(groupName, remoteFileName);
        } catch (IOException e) {
            logger.error("IO Exception: Get File from Fast DFS failed" + e.getMessage(), e);
        } catch (Exception e) {
            logger.error("Non IO Exception: Get File from Fast DFS failed" + e.getMessage(), e);
        }
        return null;
    }

    public static void deleteFile(String groupName, String remoteFileName) throws Exception {
        storageClient.delete_file(groupName, remoteFileName);
    }

    public static StorageServer[] getStoreStorages(String groupName) throws IOException {

        return trackerClient.getStoreStorages(trackerServer, groupName);
    }

    public static ServerInfo[] getFetchStorages(String groupName, String remoteFileName) throws IOException {
        return trackerClient.getFetchStorages(trackerServer, groupName, remoteFileName);
    }
}
